package domain

import (
	"errors"
	"gluenet/internal/glue-srvp/domain/dependency"
	"gluenet/internal/glue-srvp/domain/entity"
	"gluenet/internal/glue-srvp/domain/po"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
)

func init() {
	prepare.RegisterService(func() {
		domain := NewRepoDomain()
		prepare.InjectDependency(func() *Repo {
			return domain
		})
	})
}

type Repo struct {
	MetaRepo   dependency.MetaRepo
	ConfigRepo dependency.ConfigMetaRepo
}

func NewRepoDomain() *Repo {
	domain := &Repo{}
	prepare.FetchDependency(&domain.MetaRepo)
	prepare.FetchDependency(&domain.ConfigRepo)
	return domain
}

func (r *Repo) Create(auth infra.AuthInfo, req vo.CreateRepoReq) (interface{}, error) {
	var repo entity.Repo
	repo.SetEngine(r.MetaRepo.Engine())
	return repo.AddRepoWithAuth(auth, req)
}

func (r *Repo) Delete(auth infra.AuthInfo, id int64) (interface{}, error) {
	var repo entity.Repo
	repo.SetEngine(r.MetaRepo.Engine())
	return repo.DelRepoWithAuth(auth, id)
}

func (r *Repo) Update(auth infra.AuthInfo, req vo.UpdateRepoReq) (interface{}, error) {
	var repo entity.Repo
	repo.SetEngine(r.MetaRepo.Engine())
	return repo.UptRepoWithAuth(auth, req)
}

func (r *Repo) FindBy(auth infra.AuthInfo, page *vo.Page, query map[string]interface{}) (interface{}, error) {
	var repo entity.Repo
	repo.SetEngine(r.MetaRepo.Engine())
	return repo.ListRepoWithAuth(page, auth, query)
}

func (r *Repo) ListRepoCharts(auth infra.AuthInfo, repoId int64) (interface{}, error) {
	var repo entity.Repo
	repo.SetEngine(r.MetaRepo.Engine())
	p, err := repo.GetRepoById(repoId)
	if err != nil {
		return nil, err
	}
	return r.MetaRepo.ListRepoCharts(p.Name, p.Url)
}

func (r *Repo) ImportRepoChart(auth infra.AuthInfo, req vo.ImportRepoChartsReq) (interface{}, error) {
	var repo entity.Repo
	repo.SetEngine(r.MetaRepo.Engine())
	p, err := repo.GetRepoById(req.RepoId)
	if err != nil {
		return nil, err
	}

	for chartName, versions := range req.Charts {
		for _, version := range versions {
			info, err := r.MetaRepo.ImportRepoChart(p.Name, chartName, version, auth.UserId)
			if err != nil {
				return nil, err
			}
			// todo import app
			var obj entity.Config
			obj.ConfigFile.IsUploads = false

			obj.Name = info.Name
			obj.Describe = info.Describe
			obj.Property = infra.PropertyApplication
			obj.Kind = infra.ConfigKindHelmChart
			obj.Version = "1"
			obj.DetailRepoValue.Charts = info.Detail
			obj.DetailRepoValue.OptionJaeger = infra.Enable
			obj.DetailRepoValue.OptionLinkerd = infra.Enable

			if err = r.ConfigRepo.AddConfig(&obj, auth); err != nil {
				return nil, err
			}

			var repoToConfig po.RepoToConfig
			repoToConfig.RepoId = req.RepoId
			repoToConfig.ConfigId = obj.Id
			affect, err := r.MetaRepo.Engine().InsertOne(&repoToConfig)
			if err != nil {
				return nil, err
			}
			if affect == 0 {
				return nil, errors.New("affect row 0")
			}
		}
	}
	return nil, err
}
